Ordinary
About

Spring 환경 변수

profileordilov / 2022. 2. 14

Spring 환경별 환경 변수

로컬환경, 테스트환경, 배포환경등 다양한 환경에 따라 변수값을 바꿔줘야할 때가 있습니다.

가장 간단하게 적용해볼 수 있는 방법은 커맨드라인이나 환경변수 인자 값으로 넣어주고 실행하는 것입니다.

하지만 이렇게 사용하는 경우 변수가 많아지면 복잡하고, 다른 사람과 공유하기 힘듭니다.

이런 경우 설정파일에 값을 정리하고 프레임워크에서 불러오는 방법을 주로 사용합니다.

Spring에서는 주로 .properties, .yml 파일 형식을 이용합니다.

환경 변수로 사용할 수 있는 요소는 다양한데 값들이 겹치는 경우 우선순위에 따라 적용됩니다.

예를 들어 .properties.yml에서 값이 겹친다면 .properties가 우선됩니다.

@Value

import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class MyBean { @Value("${name}") private String name; // ... }

@Value를 사용한 방법은 SpEL(Spring Expression Language)를 지원합니다. 정규식, 클래스, 선언문, 컬렉션등 다양한 표현을 이용한 값을 불러올 수 있습니다. 이런 표현식을 통해 위에서 말한 환경변수에 해당하는 값들과 일치하는 경우 불러와 사용할 수 있습니다.

@ConfigurationProperties

@ConfigurationProperties는 값이 많을 때, 그리고 복잡할 수록 유용합니다. 먼저 사용하려면 configuration processor 플러그인과 설정이 필요합니다.

annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

그리고 아래와 같이 설정을 추가해야 합니다.

@Configuration() @EnableConfigurationProperties(MyProperties.class) public class MyConfiguration { }

이후 간단하게 값을 명시해주는 경우 @ConfigurationProperties로 가능합니다. 다른 곳에서 값을 사용하려면 당연히 getter가 필요할 겁니다. setter의 경우 properties 값이 바인딩 될 때 사용되므로 필수로 넣어줘야 합니다. 롬복을 사용한다면 둘다 간단하게 적용할 수 있습니다.

@ConfigurationProperties("my.service") public class MyProperties { private boolean enabled; private InetAddress remoteAddress; private final Security security = new Security(); // getters / setters... public static class Security { private String username; private String password; private List<String> roles = new ArrayList<>(Collections.singleton("USER")); // getters / setters... } }

열려있는 setter

위에서 봤듯이 값을 바인딩하기 위해서 setter가 필수로 필요한데 이는 다른 곳에서 값을 변경할 수 있습니다. 보통 환경변수 값은 변경하지 않고 불변값으로 사용하므로 이를 막을 수 있는 방법을 제공합니다. 멤버 변수를 final로 선언하고 @ConstructorBinding을 선언하면 됩니다.

@ConstructorBinding @ConfigurationProperties(prefix = "my.service") public class MyProperties { private final String redirectUri; private final String clientId; private final String clientSecret; private final String accessToken; }

변수 작성 시 이름 짓는 규칙

Java에서 변수명을 보통 camel case로 작성하듯 yaml 변수 명도 자주 사용하는 방식이 있습니다. Kebab case로 두 단어를 - 로 구분해 표시합니다. Spring 문서에서 제공한 규칙은 다음과 같습니다.

  • first-name : 제일 추천하는 방식
  • first_name : 대체 방식
  • firstName : camel case 방식
  • FIRSTNAME : 시스템 환경 변수 방식

어느 것을 써도 일관성 있게 사용하기만 하면 되지만 추천하는 방식을 사용하면 값을 불러올 때 달라지게 됩니다. first-name 과 firstName 처럼 값이 달라지게 되는데 @ConstructorBinding에서는 이를 해석해 바인딩합니다. 따라서 어느쪽을 써도 Java에서 camel case로 작성하면 그대로 사용할 수 있습니다.

메타 데이터 지원

추가적으로 @ConstructorBinding에서는 메타 데이터를 지원하는데 IDE에서 변수에 대한 자동완성을 돕습니다. yml 파일을 작성할 때도 변수에 키 값들이 자동완성되거나 설명을 볼 수 있었을텐데 그런 값들을 지정할 수 있습니다.